
// <copyright file="Misc.cs" company="Subhadra Software Solutions">
//   
// </copyright>
// <summary>
//   The misc.
// </summary>

namespace SubhadraSolutions.Sharp.Utils.Extensions
{
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Linq;

    using SubhadraSolutions.Sharp.Utils.Collections.Generic;
    using SubhadraSolutions.Sharp.Utils.Contracts;

    /// <summary>
    /// The misc.
    /// </summary>
    public static class Misc
    {
        // public static bool AddIfDoesNotExistWithLock<T>(this IList<T> list, T item)
        // {
        // lock (list)
        // {
        // return AddIfDoesNotExist(list, item);
        // }
        // }
        #region Public Methods and Operators

        /// <summary>
        /// The add if does not exist.
        /// </summary>
        /// <param name="list">
        /// The list.
        /// </param>
        /// <param name="item">
        /// The item.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public static bool AddIfDoesNotExist<T>(this IList<T> list, T item)
        {
            if (!list.Contains(item))
            {
                list.Add(item);
                return true;
            }

            return false;
        }

        // public static bool AddIfDoesNotExistWithLock<Key, ParameterValue>(this IDictionary<Key, ParameterValue> dictionary, Key key, ParameterValue value)
        // {
        // lock (dictionary)
        // {
        // return AddIfDoesNotExist(dictionary, key, value);
        // }
        // }
        /// <summary>
        /// The add if does not exist.
        /// </summary>
        /// <param name="dictionary">
        /// The dictionary.
        /// </param>
        /// <param name="key">
        /// The key.
        /// </param>
        /// <param name="value">
        /// The value.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <typeparam name="TValue">
        /// </typeparam>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public static bool AddIfDoesNotExist<T, TValue>(this IDictionary<T, TValue> dictionary, T key, TValue value)
        {
            if (!dictionary.ContainsKey(key))
            {
                dictionary.Add(key, value);
                return true;
            }

            return false;
        }

        /// <summary>
        /// The build dictionary.
        /// </summary>
        /// <param name="uniqueItems">
        /// The unique items.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <returns>
        /// The <see cref="Dictionary"/>.
        /// </returns>
        public static Dictionary<string, T> BuildDictionary<T>(IEnumerable<T> uniqueItems) where T : IUnique
        {
            return uniqueItems.ToDictionary(item => item.Name);
        }

        /// <summary>
        /// The create if does not exist and get.
        /// </summary>
        /// <param name="dictionary">
        /// The dictionary.
        /// </param>
        /// <param name="key">
        /// The key.
        /// </param>
        /// <param name="isCreated">
        /// The is created.
        /// </param>
        /// <typeparam name="TKey">
        /// </typeparam>
        /// <typeparam name="TValue">
        /// </typeparam>
        /// <returns>
        /// The <see cref="TValue"/>.
        /// </returns>
        public static TValue CreateIfDoesNotExistAndGet<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, out bool isCreated) where TValue : new()
        {
            if (dictionary.ContainsKey(key))
            {
                isCreated = false;
                return dictionary[key];
            }

            var v = new TValue();
            dictionary.Add(key, v);
            isCreated = true;
            return v;
        }

        /// <summary>
        /// The create if does not exist and get.
        /// </summary>
        /// <param name="dictionary">
        /// The dictionary.
        /// </param>
        /// <param name="key">
        /// The key.
        /// </param>
        /// <typeparam name="TKey">
        /// </typeparam>
        /// <typeparam name="TValue">
        /// </typeparam>
        /// <returns>
        /// The <see cref="TValue"/>.
        /// </returns>
        public static TValue CreateIfDoesNotExistAndGet<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key) where TValue : new()
        {
            bool isCreated;
            return CreateIfDoesNotExistAndGet(dictionary, key, out isCreated);
        }

        /// <summary>
        /// The export as dictionary.
        /// </summary>
        /// <param name="uniqueItems">
        /// The unique items.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <returns>
        /// The <see cref="Dictionary"/>.
        /// </returns>
        public static Dictionary<string, T> ExportAsDictionary<T>(this IEnumerable<T> uniqueItems) where T : IUnique
        {
            return BuildDictionary(uniqueItems);
        }

        /// <summary>
        /// The export as dictionary.
        /// </summary>
        /// <param name="collection">
        /// The collection.
        /// </param>
        /// <returns>
        /// The <see cref="Dictionary"/>.
        /// </returns>
        public static Dictionary<string, string> ExportAsDictionary(this NameValueCollection collection)
        {
            return GeneralHelper.BuildDictionaryFromNameValueCollection(collection);
        }

        // public static ParameterValue GetIfExistsWithLock<Key, ParameterValue>(this IDictionary<Key, ParameterValue> dictionary, Key key)
        // {
        // lock (dictionary)
        // {
        // return GetIfExists(dictionary, key);
        // }
        // }
        /// <summary>
        /// The get if exists.
        /// </summary>
        /// <param name="dictionary">
        /// The dictionary.
        /// </param>
        /// <param name="key">
        /// The key.
        /// </param>
        /// <typeparam name="Key">
        /// </typeparam>
        /// <typeparam name="Value">
        /// </typeparam>
        /// <returns>
        /// The <see cref="Value"/>.
        /// </returns>
        public static Value GetIfExists<Key, Value>(this IDictionary<Key, Value> dictionary, Key key)
        {
            if (dictionary.ContainsKey(key))
            {
                return dictionary[key];
            }

            return default(Value);
        }

        /// <summary>
        /// The to chunk list.
        /// </summary>
        /// <param name="enumerable">
        /// The enumerable.
        /// </param>
        /// <typeparam name="T">
        /// </typeparam>
        /// <returns>
        /// The <see cref="ChunkList"/>.
        /// </returns>
        public static ChunkList<T> ToChunkList<T>(this IEnumerable<T> enumerable)
        {
            return new ChunkList<T>(enumerable);
        }

        #endregion Public Methods and Operators
    }
}
